package org.ohos.rajawali3d.examples.examples.interactive;

import ohos.aafwk.content.Intent;
import ohos.app.Context;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.ResourceManager;
import ohos.sensor.agent.CategoryOrientationAgent;
import ohos.sensor.bean.CategoryOrientation;
import ohos.sensor.data.CategoryOrientationData;
import ohos.sensor.listener.ICategoryOrientationDataCallback;
import org.ohos.rajawali3d.ResourceTable;
import org.ohos.rajawali3d.examples.examples.AExampleFragment;
import org.rajawali3d.Object3D;
import org.rajawali3d.lights.DirectionalLight;
import org.rajawali3d.loader.LoaderAWD;
import org.rajawali3d.materials.Material;
import org.rajawali3d.materials.methods.DiffuseMethod;
import org.rajawali3d.materials.textures.CubeMapTexture;
import org.rajawali3d.math.vector.Vector3;

public class AccelerometerFragment extends AExampleFragment implements ICategoryOrientationDataCallback {

    private final static float ALPHA = 0.8f;
    private final static int SENSITIVITY = 5;
    private static final long INTERVAL = 0L;

    private float mGravity[];
    private CategoryOrientation orientationSensor;
    private CategoryOrientationAgent categoryOrientationAgent = new CategoryOrientationAgent();

    @Override
    public void onStart(Intent savedInstanceState) {
        super.onStart(savedInstanceState);

        mGravity = new float[3];
        orientationSensor = categoryOrientationAgent.getSingleSensor(
                CategoryOrientation.SENSOR_TYPE_ORIENTATION);
        if (orientationSensor != null) {
            categoryOrientationAgent.setSensorDataCallback(
                    this, orientationSensor, INTERVAL);
        }
    }

    @Override
    public AExampleRenderer createRenderer() {
        return new AccelerometerRenderer(getContext(), this);
    }

    @Override
    public void onSensorDataModified(CategoryOrientationData categoryOrientationData) {
        mGravity[0] = ALPHA * mGravity[0] + (1 - ALPHA) * categoryOrientationData.values[0];
        mGravity[1] = ALPHA * mGravity[1] + (1 - ALPHA) * categoryOrientationData.values[1];
        mGravity[2] = ALPHA * mGravity[2] + (1 - ALPHA) * categoryOrientationData.values[2];

        ((AccelerometerRenderer) mRenderer).setAccelerometerValues(
                categoryOrientationData.values[1] - mGravity[1] * SENSITIVITY,
                categoryOrientationData.values[0] - mGravity[0] * SENSITIVITY, 0);
    }

    @Override
    public void onAccuracyDataModified(CategoryOrientation categoryOrientation, int i) {

    }

    @Override
    public void onCommandCompleted(CategoryOrientation categoryOrientation) {

    }

    private final class AccelerometerRenderer extends AExampleFragment.AExampleRenderer {
        private DirectionalLight mLight;
        private Object3D mMonkey;
        private Vector3 mAccValues;

        public AccelerometerRenderer(Context context, AExampleFragment fragment) {
            super(context, fragment);
            mAccValues = new Vector3();
        }

        @Override
        protected void initScene() {
            try {
                mLight = new DirectionalLight(0.1f, -1.0f, -1.0f);
                mLight.setColor(1.0f, 1.0f, 1.0f);
                mLight.setPower(1);
                getCurrentScene().addLight(mLight);
                ResourceManager resManager = mContext.getResourceManager();
                RawFileEntry rawFileEntry = resManager.getRawFileEntry("resources/rawfile/awd_suzanne.awd");
                final LoaderAWD parser = new LoaderAWD(mContext.getResourceManager(), mTextureManager, rawFileEntry);
                parser.parse(mContext);

                mMonkey = parser.getParsedObject();

                getCurrentScene().addChild(mMonkey);

                getCurrentCamera().setZ(7);

                int[] resourceIds = new int[]{ResourceTable.Media_posx, ResourceTable.Media_negx,
                        ResourceTable.Media_posy, ResourceTable.Media_negy, ResourceTable.Media_posz,
                        ResourceTable.Media_negz};

                Material material = new Material();
                material.enableLighting(true);
                material.setDiffuseMethod(new DiffuseMethod.Lambert());

                CubeMapTexture envMap = new CubeMapTexture("environmentMap", resourceIds);
                envMap.isEnvironmentTexture(true);
                material.addTexture(envMap);
                material.setColorInfluence(0);
                mMonkey.setMaterial(material);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onRender(long elapsedRealtime, double deltaTime) {
            super.onRender(elapsedRealtime, deltaTime);
            mMonkey.setRotation(mAccValues.x, mAccValues.y, mAccValues.z);
        }

        void setAccelerometerValues(float x, float y, float z) {
            mAccValues.setAll(-x, -y, -z);
        }

    }

}
